home *** CD-ROM | disk | FTP | other *** search
- /*\
- *
- * This ARexx script will randomly disturb the points in an object file.
- *
- * Usage: Jitter <ObjectFileName> <X Distance> [Y Distance] [Z Distance]
- * Distance is how far to move a point in a given direction.
- * If you leave out the Y or Z sizes Jitter will duplicate the
- * previous size. Ex. Using just one number jitter an object evenly
- * while using a large X and 1 for Y and Z would only affect points
- * along the X axis. This is the GLOBAL axis, not the object.
- * This script will parse through grouped objects as well and do each
- * one as it finds them. It can be a little slow for huge objects.
- * For a nice rough ground effect you can use a plane with lots of
- * subdivisions. Play around with scaling each axis diffrently for some
- * interesting effects.
- *
- * V1.0 Nov-22-94
- * IanSmith@psu.edu
- *
- \*/
-
- Numeric Digits 14 /* Need at least 12 to handle 32 bits */
-
- Parse Arg FileName Amount.X Amount.Y Amount.Z .
-
- If Amount.X="" Then Do
- Say "Usage: Jitter <ObjectFileName> <X Distance> [Y Distance] [Z Distance]"
- Say "Please enter at least an X value. More help is in this file."
- Exit
- End
- If Amount.Y="" Then Amount.Y=Amount.X
- If Amount.Z="" Then Amount.Z=Amount.Y
-
- If Open(In,FileName,"R")=0 Then Do
- Say "ERROR: I can't open" FileName
- Exit
- End
- Call Open(Out,FileName||".Out","W")
-
- If InOut(4)~="FORM" Then Do /* Is it a FORM? */
- Say "This is not an IFF FORM file."
- Exit
- End
- Size=C2D(InOut(4))
- Call ParseHUNK(Size,InOut(4))
-
- Exit
-
- ParseHUNK: PROCEDURE EXPOSE Amount. /* Recursive function */
- Parse Arg MaxSize , HunkName
- TotalSize=0
- Do Until TotalSize>=MaxSize
- Name=InOut(4)
- Size=C2D(InOut(4))
- If Size//2=1 Then /* Pad IFF hunk if odd */
- Size=Size+1
- If Name="OBJ " | Name="DESC" | Name="TOBJ" | Name="ISTG" | Name="SOBJ" Then Do /* Recurse into these hunks */
- TotalSize=TotalSize+ParseHUNK(Size,Name)+8
- Iterate
- End
- TotalSize=TotalSize+Size+8 /* Add header size */
- If Name="NAME" Then Do
- ObjName=InOut(Size)
- End; Else If Name="PNTS" Then Do /* Only parse Points */
- Points=C2D(InOut(2))
- Say "Jittering" ObjName "with" Points "points"
- Do Pcn=1 To Points
- Call WriteCH(Out,FToBin(BinToF(ReadCH(In,4))+(RandU()*Amount.X*2-Amount.X)))
- Call WriteCH(Out,FToBin(BinToF(ReadCH(In,4))+(RandU()*Amount.Y*2-Amount.Y)))
- Call WriteCH(Out,FToBin(BinToF(ReadCH(In,4))+(RandU()*Amount.Z*2-Amount.Z)))
- End
- End; Else Do
- Call InOut(Size)
- End
- End
- Return TotalSize
-
- FToBin: PROCEDURE
- Parse Arg ConvertBNum /* Convert back to Imagine FP. */
- If ConvertBNum<0 Then /* D2C(2**31) is broken! */
- ConvertBNum=2**32+ConvertBNum*65536
- Else
- ConvertBNum=ConvertBNum*65536
- Return Right(D2C(ConvertBNum/65536%1),2,'00'x)||Right(D2C(ConvertBNum//65536%1),2,'00'x)
-
- BinToF: PROCEDURE /* Convert from Imagine FP nums */
- Parse Arg ConvertFNum /* to something we can work with. */
- Return C2D(ConvertFNum)/65536
-
- InOut:
- Parse Arg Bytes . /* Read bytes, write them */
- InOutData=ReadCH(In,Bytes) /* back out and return to */
- Call WriteCH(Out,InOutData) /* the calling function. */
- Return InOutData
-